/**
* 苏州海管家物流科技有限公司（https://www.hgj.com/）.
* 苏公网安备32059002003385号© 2015-2022 Hgj.com All Rights Reserved. | 苏ICP备15030950号.
* @Date: 2022.08.14.
* @Author
* @Description 企点管理后台 - 支付管理 模块.
*/
<script setup lang="ts" name="PaymentManage">
import { ref, reactive, nextTick } from "vue"
import type { FormInstance, FormRules } from 'element-plus'
import dayjs from 'dayjs'
import {getData, postData} from '@/api/index'
import QRCode from 'qrcode'
import urls from "@/api/urls"
import {IKey} from "@/typings"
import QueryCondition from '@/components/QueryCondition.vue'
import {userStore} from "@/store"


const user = userStore()
console.log('user-----------------', user)

let total = 0
let active = 1
// eslint-disable-next-line no-unused-vars
let rowData = {}
let tableList = []
let dialogVisible = false
let imgUrl = ''
let loading = false
let creatCodeId = '' // 创建付款码 生成的 数据 id 记录查看使用
let payExpireTime = '' // 支付剩余时间
let saveSuccess = false


let query = {
    num: 1,
    size: 10
}

const productObj = {
    0: '--',
    1: '企点货代Q宝-基础版',
    2: '企点货代Q宝-基础版增值包',
    3: '企点货代Q宝-标准版',
    4: '企点货代Q宝-标准版增值包',
    5: '货代Q宝-基础版升级标准版'
}
const typeObj = {
    0: '--',
    1: '新销售',
    2: '加工号',
    3: '续费',
    4: '升级'
}
const statusObj = {
    0: '待付款',
    1: '支付成功',
    2: '订单超时',
    3: '交易失败',
    4: '交易关闭'
}
const statusColor = {
    0: 'status0',
    1: 'status1',
    2: 'status2',
    3: 'status3',
    4: 'status4'
}
// 支付状态: PAY_WAITE(0, "待付款"), PAY_SUCCESS(1, "支付成功"),ORDER_TIMEOUT(2, "订单超时"), PAY_FAIL(3, "交易失败"), PAY_CANCEL(4, "交易关闭")
const paymentStatus = [{
    value: -1,
    label: '全部'
}, {
    value: 0,
    label: '待付款'
}, {
    value: 1,
    label: '支付成功'
}, {
    value: 2,
    label: '订单超时'
}, {
    value: 3,
    label: '交易失败'
}, {
    value: 4,
    label: '交易关闭'
}]
const productOption= [{
    value: 1,
    label: '企点货代Q宝-基础版'
}, {
    value: 2,
    label: '企点货代Q宝-基础版增值包'
}, {
    value: 3,
    label: '企点货代Q宝-标准版'
}, {
    value: 4,
    label: '企点货代Q宝-标准版增值包'
}, {
    value: 5,
    label: '货代Q宝-基础版升级标准版'
}]
const typeOption = [{
    value: '1',
    label: '新销售'
}, {
    value: 2,
    label: '加工号'
}, {
    value: 3,
    label: '续费'
}, {
    value: 4,
    label: '升级'
}]
const queryList = ref([{
    id: 'compName',
    value: '',
    defaultValue: '',
    typeName: 'input',
    label: "公司名称",
    placeholder: '请输入公司名称'
}, {
    id: 'orderNo',
    value: '',
    defaultValue: '',
    typeName: 'input',
    label: "订单编号",
    placeholder: '请输入订单编号'
}, {
    id: 'payStatus',
    value: '',
    defaultValue: '',
    typeName: 'select',
    label: "支付状态",
    options: [...paymentStatus],
    placeholder: '请选择支付状态'
}, {
    id: '__dateRange$fromDate$toDate',
    value: '',
    defaultValue: '',
    typeName: 'daterange',
    label: "创建时间",
    startPlaceholder: '开始日期',
    endPlaceholder: '结束日期'
}])
let originQuery = {
    compName: '',
    orderNo: '',
    submitTime: '',
    toDate: '', // 结束时间
    fromDate: '', // 开始时间
    payStatus: -1
}
console.log('originQuery--------------', originQuery)
let ruleForm = reactive({
    compName: '',
    saleName: '',
    dealProduct: '', // 成交产品:([1:企点货代Q宝-基础版],[2:企点货代Q宝-基础版增值包],[3:企点货代Q宝-标准版],[4:企点货代Q宝-标准版增值包],[5:货代Q宝基础版升级标准版])
    dealType: '', // 成交类型:([1:新销售],[2:加工号],[3:续费],[4:升级])
    num: '',
    orderAccount: '',
    year: '',
    month: '',
    date: ''
})
const ruleFormRef = ref<FormInstance>()
console.log('ruleFormRef--------', ruleFormRef)
const rules = reactive<FormRules>({
    compName: [
        { required: true, message: '请填写公司全称', trigger: 'blur' }
    ],
    saleName: [{ required: true, message: '请填写销售人员', trigger: 'blur' }],
    dealProduct: [
        { required: true, message: '请选择成交产品', trigger: 'change' }
    ],
    dealType: [
        { required: true, message: '请选择成交类型', trigger: 'change' }
    ],
    num: [
        { type: 'number', required: true, message: '请填写数量', trigger: 'blur' }, { type: 'number', pattern: /^[1-9]\\d*$/, message: '请输入1-999正整数', trigger: 'change' }
    ],
    date: [
        { required: true, message: '请填写年限', trigger: 'blur' }
    ],
    orderAccount: [
        { required: true, message: '请填写金额', trigger: 'blur' },
        { pattern: /^(([0-9]+)|([0-9]+\.[0-9]{0,2}))$/, message: '请输入0.01-999999正数, 最多支持2位小数', trigger: 'change' }
    ]
})


// $store.getters.user

const handleQuery = async () => {
    const params = {...originQuery}
    query = { ...query, ...params }
    query.num = 1
    searchFunc()
}
/**
*@Description 数据查询 .
*@Return .
**/
const searchFunc = async () => {
    let res = await postData({ ...query }, urls.paymentListUrl)
    tableList = res.data.records
    total = res.data.total
}
searchFunc()

const handlePreClick = () => {
    active = 1
    saveSuccess = true
}
/**
 *@Description 新建付款码 按钮 .
 *@Return .
**/
const handleEditClick = (formEl: FormInstance | undefined) => {
    active = 1
    saveSuccess = false
    dialogVisible = true
    nextTick(() => {
        const obj = {
            year: '',
            month: '',
            date: ''
            // saleId: user.userId,

            // saleName: user.userName
        }
        ruleForm = {...ruleForm, ...obj}
        if (!formEl) return
        formEl.resetFields()
    })
}
/**
 *@Description 查看二维码 .
 *@Return .
**/
const handleSeeClick = async (row) => {
    rowData = { ...row }
    ruleForm = { ...row }
    ruleForm.date = row.year || row.month
    if (row.year === 0) ruleForm.year = ''
    if (row.month === 0) ruleForm.month = ''
    methodSeeCode(row.id)
}
/**
 *@Description saveSuccess: true 保存成功 - 只能查看了 .
 *@Return 查看、生成 都 调用下 生成付款码接口.
**/
const handleCreatClick = async (formEl: FormInstance | undefined) => {
    if (!formEl) return

    if (saveSuccess) {
        methodSeeCode(creatCodeId)
    } else {
        await formEl.validate((valid, fields) => {
            if (valid) {
                const params = {...ruleForm}
                /* params.orderAccount = Number(params.orderAccount)
                   delete params.date
                   params.id = rowData.id
                   params.orderNo = rowData.orderNo */
                loading = true
                postData({...params}, urls.savePaymentUrl).then(res => {
                    active = 2
                    saveSuccess = true
                    const { data } = res
                    creatCodeId = data
                    data && methodSeeCode(data)
                    handleReset()
                    console.log('save 返回：', res)
                })
            } else {
                console.log('error submit!!!', fields)
                return false
            }
        })
    }
}
const methodSeeCode = async (id: string) => {
    const res = await getData({}, `${urls.seeCodeUrl}/${id}`)

    const { qrCode } = res.data
    dialogVisible = true
    active = 2
    payExpireTime = res.data.payExpireTime

    nextTick(() => {
        loading = false
        qrCode ? creatQrCode(qrCode) : imgUrl = ''
    })
}
/**
         *@Description 复制 付款码.
         *@Return .
         **/
const handleCopyClick = () => {
    downloadBase64(imgUrl)
    copyImgCode(imgUrl)
}
/**
         *@Description 复制图片 .
         *@Return .
         **/
const  copyImgCode = async (url: string) => {
    try {

        /* http
                   base64ToUrl(url)
                   const testImg = document.querySelector('#copyCodeImg')
                   const selection = window.getSelection()
                   if (selection.rangeCount > 0) {
                       selection.removeAllRanges()
                   }
                   // // 选中元素→range→selection是一一对应的，即选区必须连续，不可以有分开的多个区域。另外，被选元素必须在dom树上，不可以是游离元素，
                   // // 并且实践发现display不能为none，visibility不能为hidden，即使不需要渲染。也就是说我可以创建一个游离元素，插入dom树，
                   // // 选择后copy，然后立刻从dom树移出，整个过程都在浏览器下一次渲染之前，所以页面上没有任何变化。
                   const range = document.createRange()
                   range.selectNode(testImg)
                   // // 该Selection.addRange()方法将 a 添加 Range到 a Selection。 只有firefox支持多范围
                   selection.addRange(range)
                   document.execCommand('copy')
                   selection.removeAllRanges() */

        /* https
                   const data = await fetch(url)
                   console.log('data-------------', data)
                   const blob = await data.blob()
                   console.log('blob-------------', blob)
                   
                   await navigator.clipboard.write([
                       new window.ClipboardItem({
                           [blob.type]: blob,
                       }),
                   ])
                   $message.success('复制成功') */
        console.log('Image copied.', url)
    } catch (err) {
        console.error('err:', err)
    }
}
/**
 *@Description 下载图片 .
 *@Return .
**/
const downloadBase64 = (base64: string) => {
    const arr = base64.split(',')
    const bytes = atob(arr[1])
    let ab = new ArrayBuffer(bytes.length)
    let ia = new Uint8Array(ab)
    for (let i = 0; i < bytes.length; i++) {
        ia[i] = bytes.charCodeAt(i)
    }
    const blob = new Blob([ab], { type: 'application/octet-stream' })
    const url = URL.createObjectURL(blob)
    const time = dayjs().format('YYYY-MM-DD HH:mm:ss')
    const a = document.createElement('a')
    a.download = `付款码-${time}.png` // 这里写保存时的图片名称
    a.href = url
    a.click()
}
const handleCloseClick = () => {
    active = 1
    dialogVisible = false
}
const handleYearChange = () => {
    const str = ruleForm.year.toString()
    if (Number(ruleForm.year) > 10) {
        return ruleForm.year = str.slice(0, 1)
    }
    if (!validateInteger(ruleForm.year)) {
        ruleForm.year = ''
    }
    ruleForm.date = ruleForm.year
}
const handleMonthChange = () => {
    const str = ruleForm.month.toString()
    if (Number(ruleForm.month) > 12) {
        return ruleForm.month = str.slice(0, 1)
    }
    if (!validateInteger(ruleForm.month)) {
        ruleForm.month = ''
    }
    ruleForm.date = ruleForm.month
}
/**
 *@Description 校验 正整数 .
 *@Return .
**/
const validateInteger = (num: string) => {
    return /^[1-9]\d*$/.test(num)
}
/**
 *@Description 创建二维码 .
 *@Return .
**/
const creatQrCode = (urlData: any) => {
    const opts = {
        margin: 1,
        quality: 0.3,
        type: 'image/png',
        errorCorrectionLevel: 'H',
        color: {
            dark: '#000',
            light: '#fff'
        }
    }

    QRCode.toDataURL(urlData, opts, (err, url) => {
        if (err) {
            throw err
        }
        imgUrl = url
    })
    /* with then
               QRCode.toDataURL('I am a pony!').then(url => {
                   console.log('then url:', url)
               }).catch(err => {
                   console.error(err)
               })
               With async/await
               const generateQR = async text => {
                   try {
                       console.log('await url:', await QRCode.toDataURL(text))
                   } catch (err) {
                       console.error(err)
                   }
               }
               generateQR('6') */
}
/**
         *@Description 重置 .
         *@Return .
         **/
const handleReset = () => {
    query = {
        num: 1,
        size: 10
    }
    originQuery = {...query, payStatus: -1}
    handleQuery()
}
const handlePageChange = () => {
    searchFunc()
}

/**
 *@Description 查询组件 查询按钮 emit 方法监听 .
 *@Return { id: value }.
 **/
const renderSearch = (data: IKey) => {
    console.log('renderSearch--------', data)
    /* params = {...params, ...data}
       getClueList() */
}
/**
 *@Description 查询组件 重置按钮 emit 方法监听 .
 *@Return { id: defaultValue }.
 **/
const renderReset = (data: IKey) => {
    console.log('renderReset', data)
    /* params = {...params, ...data}
       params.submitEnd = ''
       params.submitStart = ''
       getClueList() */
}

</script>
<template>
  <!-- 查询区域 -->
  <QueryCondition title="我是父组件标题" :queryList="queryList" @emitSearch="renderSearch" @emitReset="renderReset" />

  <section>
    <el-button class="mb10" type="primary" @click="handleEditClick"> 新建付款码 </el-button>

    <el-table ref="table" :data="tableList" border>
      <el-table-column align="center" label="序号" type="index" width="50px" :index="(index) => query.size * (query.num - 1) + index + 1" />
      <el-table-column label="公司名称" prop="compName" />
      <el-table-column label="销售" prop="saleName" width="80px" />
      <el-table-column label="订单编号" prop="orderNo" />
      <el-table-column label="成交产品" prop="dealProduct">
        <template #default="{ row }">{{ productObj[row.dealProduct] || '--' }}</template>
      </el-table-column>
      <el-table-column label="成交类型" prop="dealType" width="80px">
        <template #default="{ row }">{{ typeObj[row.dealType] || '--' }}</template>
      </el-table-column>
      <el-table-column label="数量" prop="num" width="80px" />
      <el-table-column label="年限" prop="year" width="90px">
        <template #default="{ row }">
          <span v-if="row.year">{{ row.year }}年</span>
          <span v-if="row.month">{{ row.month }}月</span>
        </template>
      </el-table-column>
      <el-table-column label="订单金额（元）" prop="orderAccount" width="120px" />
      <el-table-column label="已支付金额（元）" prop="actualAccount" width="135px" />
      <el-table-column label="支付状态" prop="payStatus" width="80px">
        <template #default="{ row }"><span :class="statusColor[row.payStatus]">{{ statusObj[row.payStatus] || '--' }}</span></template>
      </el-table-column>

      <el-table-column label="创建时间" prop="updateTime" width="160px" />

      <el-table-column label="操作" width="100px">
        <template #default="{ row }">
          <el-button v-if="row.payStatus === 0" type="text" @click="handleSeeClick(row)"> 查看二维码 </el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="text-center py-4">
      <el-pagination
        background
        :total="total"
        :page-size="query.size"
        v-model:current-page="query.num"
        @current-change="handlePageChange"
      />
    </div>
  </section>
  <!-- 新建付款吗 弹窗 -->
  <el-dialog title="新建付款码" v-model:visible="dialogVisible" width="525px" :destroy-on-close="true">
    <el-steps :active="active" align-center>
      <el-step title="填写收款信息"></el-step>
      <el-step title="生成付款码"></el-step>
    </el-steps>
    <!-- 第一步 信息 填写 -->
    <el-form
      class="demo-ruleForm" label-width="80px" ref="ruleForm"
      :model="ruleForm" :rules="rules" v-show="active === 1">

      <el-form-item label="公司名称" prop="compName">
        <el-input v-model="ruleForm.compName" placeholder="请填写公司全称" :disabled="saveSuccess"></el-input>
      </el-form-item>
      <el-form-item label="销售" prop="saleName">
        <el-input v-model="ruleForm.saleName" :disabled="true"></el-input>
      </el-form-item>

      <el-form-item label="成交产品" prop="dealProduct">
        <el-select v-model="ruleForm.dealProduct" placeholder="请选择成交产品" :disabled="saveSuccess">
          <el-option v-for="item in productOption" :key="item.value" :label="item.label" :value="item.value"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="成交类型" prop="dealType">
        <el-select v-model="ruleForm.dealType" placeholder="请选择成交类型" :disabled="saveSuccess">
          <el-option v-for="item in typeOption" :key="item.value" :label="item.label" :value="item.value"></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="数量" prop="num">
        <el-input v-model.number="ruleForm.num" placeholder="请填写数量" :minlength="1" :maxlength="3" :disabled="saveSuccess"></el-input>
      </el-form-item>

      <el-form-item label="年限" prop="date" class="f-date">
        <el-input v-model.number="ruleForm.year" :maxlength="2" placeholder="请填写年限" :disabled="saveSuccess" @keyup="handleYearChange"></el-input><span class="year">年</span>
        <el-input v-model.number="ruleForm.month" :maxlength="2" placeholder="请填写月数" :disabled="saveSuccess" @keyup="handleMonthChange"></el-input>个月
      </el-form-item>

      <el-form-item label="订单金额" prop="orderAccount">
        <el-input v-model="ruleForm.orderAccount" :maxlength="6" placeholder="请填写金额" :disabled="saveSuccess"></el-input>
      </el-form-item>
    </el-form>
    <!-- 第二步 生成 付款吗 -->
    <div v-show="active === 2" class="qr-code">
      <div ref="qrCodeUrl" v-loading="loading" class="qr-img"><img :src="imgUrl" /></div>

      <div class="qr-icon">
        <p class="business-icon"><img src="@/assets/img/pay-icon.png" />扫码支付</p>
        <p class="gray">付款码有效时间：{{ payExpireTime || '' }}请尽快支付哦～</p>
      </div>
    </div>

    <template #footer>
      <footer class="dialog-footer">
        <el-button v-show="active === 1" @click="handleCloseClick">{{ saveSuccess ? '关 闭' : '取 消' }}</el-button>
        <el-button v-show="active === 2" @click="handleCloseClick">关 闭</el-button>
        <el-button v-show="active === 2" @click="handlePreClick">上一步</el-button>
        <el-button v-show="active === 1" type="primary" @click="handleCreatClick">{{ saveSuccess ? '查看' : '生成' }}付款码</el-button>
        <!--        <el-button v-show="active === 2" type="primary" @click="handleCopyClick">复制付款码</el-button>-->
        <el-button v-show="active === 2" type="primary" @click="handleCopyClick">下载付款码</el-button>
      </footer>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.mb10 {
  margin-bottom: 10px;
}
.f-date {
  .year {
    padding-right: 16px;
  }
  .el-input {
    width: 120px;
    margin-right: 8px;
  }
}
.el-steps {
  margin-bottom: 16px;
}
:deep(.el-step__title) {
  line-height: 22px;
  font-size: 14px;
}
.qr-code {
  display: flex;
  align-items: center;
  padding: 30px;
  border-radius: 1px;
  border: 1px solid #E1E6F0;
}
.qr-img {
  width: 180px;
  height: 180px;
  padding: 2px;
  background: #E1E6F0;
  img {
    display: block;
    width: 100%;
    height: 100%;
  }
}
.qr-icon {
  width: calc(100% - 208px);
  margin-left: 20px;
  .gray {
    font-size: 12px;
    color: #A1ABC2;
  }
}
.business-icon {
  display: flex;
  align-items: center;
  img {
    width: 84px;
    margin-right: 10px;
  }
}
// 生成二维码 加载区域
:deep(.el-loading-mask) {
    display: flex;
    align-items: center;
    justify-content: center;
}
:deep(.el-loading-spinner) {
  width: auto;
}

.status0 {
  color: #006aff;
}
.status1 {
  color: #30BF78;
}
.status2 {
  color: #FF7D00;
}
.status3 {
  color: #F46144;
}
.status4 {
  color: #D25F00;
}
</style>
